﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Routing
{
	public partial class MAIN : Form
	{
        // Define BS    ***************************************************************************
		BASESTATION BS = new BASESTATION();
        NODE        ND = new NODE();
        CLUSTER     CL = new CLUSTER();

        NODE[] sNode = new NODE[NODE.TNODE];


		public MAIN()
		{
			InitializeComponent();
		}

        private void PN_BG_MouseClick(object sender, MouseEventArgs e)
        {
            PaintCluster();
        }

        private void BT_MN_Click(object sender, EventArgs e)
        {
            PaintCluster();
            CreateNodes();
        }

        private void BT_BD_Click(object sender, EventArgs e)
        {
            BroadcastFromBS();
            FindHopCount();
        } 


        // 패널 위에 구역 표시  ********************************************************************
        public void PaintCluster()
        {
            int x = CLUSTER.iClstX;
            int y = CLUSTER.iClstY;

            Pen p = new Pen(Brushes.DarkGray);
            p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
            Graphics g = PN_BG.CreateGraphics();

            while ( y < 770 )
            {
                if ( x < 980 )
                {
                    g.DrawLine(p, x, 0, x, 770);
                    g.DrawLine(p, 0, y, 980, y);

                    x = CL.AddX( x );
                    y = CL.AddY( y );
                }
            }
        } // public void PaintCluster()


        // BS및 노드 생성하기  *********************************************************************
        public void CreateNodes()
        {
            // 노드 생성하기
            for ( int i = 0; i < NODE.TNODE; i++ )
                sNode[i] = new NODE();

            // 베이스 스테이션 생성하기
            BS.MakeBS( sNode[0] );
            PaintNode( sNode[0].nodeX, sNode[0].nodeY, true );

            // 일반 노드들 만들기
            for ( int i = 1; i < NODE.TNODE; i++ )
            {
                ND.MakeNodes( sNode[i], i );  
                PaintNode( sNode[i].nodeX, sNode[i].nodeY, false );
                sNode[i].distance = ND.MeasureDistance(BASESTATION.BS_X, BASESTATION.BS_Y, sNode[i].nodeX, sNode[i].nodeY);
            }
        } // public void CreateNodes()


        // 베이스 스테이션 그리기  *****************************************************************
        // x는 Node X값
        // y는 Node Y값
        // b가 true이면 BS, false이면 Node 그리기
        public void PaintNode( float x, float y, bool b )
        {
            if ( b == true )
            {
                SolidBrush bs   = new SolidBrush(Color.DarkBlue);
                Graphics g1     = PN_BG.CreateGraphics();

                g1.FillEllipse( bs, x, y, 7, 7 );
            }
            else
            {
                SolidBrush nd   = new SolidBrush(Color.Green);
                Graphics g2     = PN_BG.CreateGraphics();

                g2.FillRectangle(nd, x, y, 6, 6);
            }
        } // public void PaintNode( float x, float y, bool b )


        // BS에서 수신 가능한 노드 찾기  ************************************************************
        public void BroadcastFromBS()
        {
            BS.HC = 1;

            for( int i = 1; i < NODE.TNODE; i++ )
            {
                if( sNode[i].distance < NODE.RANGE )
                {
                    sNode[i].parentID   = 0;
                    DrawLineBetweenNodes(sNode[i].nodeX, sNode[i].nodeY, sNode[0].nodeX, sNode[0].nodeY);
                    sNode[i].hc         = BS.HC;
                    sNode[i].state      = true;
                }

            }
        } // public void BroadcastFromBS()


        // 홉 수로 근처 노드 찾기    ***************************************************************    
        public void FindHopCount()
        {            
            for ( int i = 0; i < BS.LMT_HC; i++ )
            {
                BroadcastBetweenNodes( BS.HC );
                BS.HC++;
            }
        } // public void FindHopCount()


        // 연결되지 않는 노드 찾기  ****************************************************************
        public void BroadcastBetweenNodes( int hc )
        {
            // 
            for( int i = 1; i < NODE.TNODE; i++ )
            {
                if( sNode[i].hc == hc )
                {
                    FindNeighborNode( sNode[i].nodeID );
                }
            }
        } // public void BroadcastBetweenNodes()


        // 이웃 노드 만들기 ************************************************************************
        public void FindNeighborNode( int prnt )
        {
            float distance = 0.0f;

            for( int i = 2; i < NODE.TNODE-1; i++)
            {
                distance = ND.MeasureDistance( sNode[i].nodeX, sNode[i].nodeY, sNode[prnt].nodeX, sNode[prnt].nodeY );
                if ( ( distance < NODE.RANGE ) && ( sNode[i].state == false ) )
                {
                    sNode[i].parentID   = sNode[prnt].nodeID;
                    DrawLineBetweenNodes(sNode[i].nodeX, sNode[i].nodeY, sNode[prnt].nodeX, sNode[prnt].nodeY);
                    sNode[i].hc         = BS.HC;
                    sNode[i].state      = true;
                }
            }
        } // public void FindNeighborNode( int prnt )


        // 노드 연결하기  **************************************************************************
        public void DrawLineBetweenNodes( float x1, float y1, float x2, float y2 )
        {
            Pen p = new Pen( Color.Gray, 1 );
            Graphics g = PN_BG.CreateGraphics();

            g.DrawLine( p, x1, y1, x2, y2 );
        } // public void DrawLineBetweenNodes
	} // the end of class
}
